package com.internetCafes.spms.web.job.task.sys;

import com.internetCafes.spms.web.certificate.entity.EmployeeInfo;
import com.internetCafes.spms.web.certificate.service.CertificateInfoService;
import com.internetCafes.spms.web.certificate.service.EmployeeInfoService;
import com.internetCafes.spms.web.certificate.vo.CertificateInfoVo;
import com.internetCafes.spms.web.tenant.model.TenantDeptInfo;
import com.internetCafes.spms.web.tenant.service.TenantDeptInfoService;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 员工信息重复去重定时工具类，仅使用一次
 * </p>
 *
 * @author Zheng
 */
@Log4j
@Component("employeeComponentTask")
public class EmployeeComponentTask {

    @Autowired
    private EmployeeInfoService employeeInfoService;

    @Autowired
    private CertificateInfoService certificateInfoService;

    @Autowired
    private TenantDeptInfoService tenantDeptInfoService;

    /**
     * 更新员工部门信息
     * <p>
     *     问题：
     *     员工部门会出现为空状态，
     *     再手动开票中，无法看到该类人信息
     * </p>
     */
    public void updateEmployeeDeptInfo() {
        /**
         * 更新员工部门信息
         *  1-将企业用户中所有employeeFlag为1，type为0的数据，将type置为23(使用sql语句实现)
         *  2-给用户设置默认部门
         *      获取employeeFlag为1，deptId为 null 或者 0 的数据
         *      通过tenantId获取企业默认第一个部门id，
         *      为对应企业id获取employeeFlag为1，deptId为null的人员信息进行更新部门id
         *   【加】：将水木石公司的排除在外
         */
        log.info("将企业用户中所有employeeFlag为1，type为0的数据，将type置为23(使用sql语句实现)");
        employeeInfoService.repairEmployeeTypeError();

        log.info("获取employeeFlag为1，deptId为null的数据");
        List<EmployeeInfo> employeeInfos = employeeInfoService.queryEmployeeNonDeptId();
        if (employeeInfos.isEmpty()) {
            return;
        }

        List<Long> tenantIds = employeeInfos.stream()
                .map(EmployeeInfo::getTenantId)
                .collect(Collectors.toList());

        Map<String, Object> params = new HashMap<>();
        params.put("tenantIds", tenantIds);
        List<TenantDeptInfo> allTenantDeptInfos = tenantDeptInfoService.query(params);
        Map<Long, List<TenantDeptInfo>> tenantDeptInfos = allTenantDeptInfos.stream()
                .collect(Collectors.groupingBy(TenantDeptInfo::getTenantId));

        log.info("为对应企业id获取employeeFlag为1，deptId为null的人员信息进行更新部门id");
        tenantDeptInfos.forEach((tenantId, deptInfos) -> employeeInfoService.updateNonDeptIdEmployees(tenantId, deptInfos.get(0).getId()));
    }

    /**
     * 员工数据去重demo
     */
    /*@Scheduled(cron = "0 33 19 * * ?")*/
    public void employeeDataRepeat() {
        /*
         * 员工人员信息去重方案
         *  1-获取所有员工信息中员工信息条数拥有两条以及两条以上的
         *  2-获取相关证书对应的所有数据
         *  3-数据处理
         *  4-数据更新
         *  5-通过SQL语句将证书类型为在职员工，employeeFlag为空的人员employeeFlag置为1
         *              将证书类型非在职员工，employeeFlag为空的人员employeeFlag置为0
         */
        log.info("开始处理数据……");
        //  1-获取所有员工信息中员工信息条数拥有两条以及两条以上的
        List<EmployeeInfo> employeeInfos = employeeInfoService.queryListForRepeat();
        if (employeeInfos.isEmpty()) {
            log.info("暂无数据处理……");
            updateEmployeeDeptInfo();
            return;
        }

        // 2-获取相关证书对应的所有数据
        List<String> idCards = employeeInfos.stream()
                .map(EmployeeInfo::getIdCard)
                .collect(Collectors.toList());
        List<CertificateInfoVo> certificates = certificateInfoService.selectInfoByIdCardsForRepeat(idCards);

        // 3-数据处理
        /**
         * 修改：
         * 需要对员工和证书进行分组 首先身份证 其次是企业id
         */
        Map<String, Map<Long, Long>> employeesByIdCardAndTenantId = employeeInfos.stream()
                .collect(Collectors.groupingBy(EmployeeInfo::getIdCard,
                        Collectors.toMap(EmployeeInfo::getTenantId, EmployeeInfo::getId)));

        Map<String, Map<Long, List<CertificateInfoVo>>> certificatesByIdCardAndTenantId = certificates.stream()
                .collect(Collectors.groupingBy(CertificateInfoVo::getIdCard,
                        Collectors.groupingBy(CertificateInfoVo::getTenantId)));

        // 4-轮询更新数据 证书employeeId
        certificatesByIdCardAndTenantId.forEach((idCard, certificatesByTenantId) -> {
            Map<Long, Long> employeesByTenantId = employeesByIdCardAndTenantId.get(idCard);
            certificatesByTenantId.forEach((tenantId, certificateInfo) -> {
                Long finalEmployId = employeesByTenantId.get(tenantId);
                List<Long> certificateIds = certificateInfo.stream()
                        .map(CertificateInfoVo::getId)
                        .collect(Collectors.toList());
                certificateInfoService.updateEmployeeIdBatch(certificateIds, finalEmployId);
            });
        });


        /*Map<String, Long> idCardWithId = employeeInfos.stream()
                .collect(Collectors.toMap(EmployeeInfo::getIdCard, EmployeeInfo::getId));
        Map<String, List<CertificateInfoVo>> idCardWithCertificate = certificates.stream()
                .collect(Collectors.groupingBy(CertificateInfoVo::getIdCard));
        // 4-轮询更新数据 证书employeeId
        idCardWithCertificate.forEach((idCard, certificateInfos) -> {
            //  获取证书id
            List<Long> certificateIds = certificateInfos.stream()
                    .map(CertificateInfoVo::getId)
                    .collect(Collectors.toList());
            // 获取最终需要修改的id
            Long finalId = idCardWithId.get(idCard);
            // 更新数据
            certificateInfoService.updateEmployeeIdBatch(certificateIds, finalId);
        });*/

        // 5-去重数据
        employeeInfos.forEach(employee -> employeeInfoService.removalRepeatEmployee(employee.getIdCard(), employee.getTenantId() , employee.getId()));
        log.info("结束处理数据……");
        log.info("开始员工employee_flag错误信息修复……");
        employeeInfoService.repairEmployeeFlagErrorInfo();
        log.info("结束员工employee_flag错误信息修复……");
        updateEmployeeDeptInfo();
    }
}
